package com.kvc.extend.papervision3d 
{
	import org.papervision3d.core.proto.CameraObject3D;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.scenes.Scene3D;

	/**
	 * Camera Rig using HPB system
	 * @author Kevin Cao
	 */
	public class CameraRig 
	{

		// controllers
		protected var headingCtrl : DisplayObject3D;
		protected var bankCtrl : DisplayObject3D;
		protected var pitchCtrl : DisplayObject3D;
		protected var posCtrl : DisplayObject3D;
		protected var camCtrl : DisplayObject3D;

		protected var camera : CameraObject3D;
		protected var scene : Scene3D;

		protected var _heading : Number = 0;
		protected var _pitch : Number = 0;
		protected var _bank : Number = 0;
		protected var _tracking : Number = 0;
		protected var _x : Number = 0;
		protected var _y : Number = 0;
		protected var _z : Number = 0;

		/**
		 * 
		 */
		public function get heading() : Number
		{
			return _heading;
		}

		public function set heading(value : Number) : void
		{
			_heading = value;
			headingCtrl.rotationY = _heading;
		}

		/**
		 * 
		 */
		public function get pitch() : Number
		{
			return _pitch;
		}

		public function set pitch(value : Number) : void
		{
			_pitch = value;
			pitchCtrl.rotationX = _pitch;
		}

		/**
		 * 
		 */
		public function get bank() : Number
		{
			return _bank;
		}

		public function set bank(value : Number) : void
		{
			_bank = value;
			bankCtrl.rotationZ = _bank;
		}

		/**
		 * 
		 */
		public function get tracking() : Number
		{
			return _tracking;
		}
		
		/**
		 * default is 1000
		 */
		public function set tracking(value : Number) : void
		{
			if(value <= 0) {
				throw new Error("CameraRig :: tracking value error");
			}
			_tracking = value;
			camCtrl.z = -_tracking;
		}

		/**
		 * 
		 */
		public function get x() : Number
		{
			return _x;
		}

		public function set x(value : Number) : void
		{
			_x = value;
			posCtrl.x = _x;
		}

		/**
		 * 
		 */
		public function get y() : Number
		{
			return _y;
		}

		public function set y(value : Number) : void
		{
			_y = value;
			posCtrl.y = _y;
		}

		/**
		 * 
		 */
		public function get z() : Number
		{
			return _z;
		}

		public function set z(value : Number) : void
		{
			_z = value;
			posCtrl.z = _z;
		}

		/**
		 * @param camera: FREE camera
		 * @param scene
		 */
		public function CameraRig(camera : CameraObject3D, scene : Scene3D) 
		{
			this.camera = camera;
			this.scene = scene;
			
			init();
		}

		protected function init() : void 
		{
			posCtrl = new DisplayObject3D();
			headingCtrl = new DisplayObject3D();
			pitchCtrl = new DisplayObject3D();
			bankCtrl = new DisplayObject3D();
			camCtrl = new DisplayObject3D();
			
			scene.addChild(posCtrl);
			posCtrl.addChild(headingCtrl);
			headingCtrl.addChild(pitchCtrl);
			pitchCtrl.addChild(bankCtrl);
			bankCtrl.addChild(camCtrl);
			
			// init default tracking
			tracking = 1000;
			
			update();
		}

		public function update() : void 
		{
			camera.copyTransform(camCtrl.world);
		}
	}
}
